package cn.drenal.capcap.config;

import cn.dev33.satoken.stp.StpInterface;
import cn.drenal.capcap.entity.*;
import cn.drenal.capcap.mapper.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 自定义权限验证接口扩展
 */
@Component
@RequiredArgsConstructor
public class StpInterfaceImpl implements StpInterface {

    private final SysAdminMapper sysAdminMapper;
    private final SysAdminRoleMapper sysAdminRoleMapper;
    private final SysRoleMapper sysRoleMapper;
    private final SysRolePermissionMapper sysRolePermissionMapper;
    private final SysPermissionMapper sysPermissionMapper;

    /**
     * 返回一个账号所拥有的权限码集合
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 获取用户ID
        String userId = loginId.toString();
        
        // 查询用户角色关联
        List<SysAdminRole> userRoles = sysAdminRoleMapper.selectList(
                new LambdaQueryWrapper<SysAdminRole>().eq(SysAdminRole::getUserId, userId));
        
        // 如果没有角色，返回空集合
        if (userRoles.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取角色ID列表
        List<Long> roleIds = userRoles.stream()
                .map(SysAdminRole::getRoleId)
                .collect(Collectors.toList());
        
        // 查询角色权限关联
        List<SysRolePermission> rolePermissions = sysRolePermissionMapper.selectList(
                new LambdaQueryWrapper<SysRolePermission>().in(SysRolePermission::getRoleId, roleIds));
        
        // 如果没有权限，返回空集合
        if (rolePermissions.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取权限ID列表
        List<Long> permissionIds = rolePermissions.stream()
                .map(SysRolePermission::getPermissionId)
                .distinct()
                .collect(Collectors.toList());
        
        // 查询权限信息
        List<SysPermission> permissions = sysPermissionMapper.selectList(
                new LambdaQueryWrapper<SysPermission>()
                        .in(SysPermission::getId, permissionIds)
                        .eq(SysPermission::getStatus, 1) // 只查询启用的权限
//                        .getWrapper()
        );
        
        // 返回权限标识列表
        return permissions.stream()
                .filter(permission -> permission.getPermission() != null && !permission.getPermission().isEmpty())
                .map(SysPermission::getPermission)
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 返回一个账号所拥有的角色标识集合
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        // 获取用户ID
        String userId = loginId.toString();
        
        // 兼容旧版本：查询管理员信息中的角色字段
        SysAdmin admin = sysAdminMapper.selectById(userId);
        List<String> roles = new ArrayList<>();
        if (admin != null && admin.getRole() != null) {
            roles.add(admin.getRole());
        }
        
        // 查询用户角色关联表
        List<SysAdminRole> userRoles = sysAdminRoleMapper.selectList(
                new LambdaQueryWrapper<SysAdminRole>().eq(SysAdminRole::getUserId, userId));
        
        // 如果没有角色关联，返回已有的角色列表
        if (userRoles.isEmpty()) {
            return roles;
        }
        
        // 获取角色ID列表
        List<Long> roleIds = userRoles.stream()
                .map(SysAdminRole::getRoleId)
                .collect(Collectors.toList());
        
        // 查询角色信息
        List<String> roleCodes = sysRoleMapper.selectList(
                new LambdaQueryWrapper<SysRole>()
                        .in(SysRole::getId, roleIds)
                        .eq(SysRole::getStatus, 1) // 只查询启用的角色
                )
                .stream()
                .map(cn.drenal.capcap.entity.SysRole::getCode)
                .collect(Collectors.toList());
        
        // 合并角色列表
        roles.addAll(roleCodes);
        
        return roles.stream().distinct().collect(Collectors.toList());
    }
}